using System;
using System.Runtime.InteropServices;

namespace Leap
{
	public class Gesture : Interface
	{
		public enum GestureType
		{
			TYPE_INVALID = -1,
			TYPE_SWIPE = 1,
			TYPE_CIRCLE = 4,
			TYPE_SCREEN_TAP,
			TYPE_KEY_TAP,
			TYPEINVALID = -1,
			TYPESWIPE = 1,
			TYPECIRCLE = 4,
			TYPESCREENTAP,
			TYPEKEYTAP
		}

		public enum GestureState
		{
			STATE_INVALID = -1,
			STATE_START = 1,
			STATE_UPDATE,
			STATE_STOP,
			STATEINVALID = -1,
			STATESTART = 1,
			STATEUPDATE,
			STATESTOP
		}

		private HandleRef swigCPtr;

		public GestureType Type => (GestureType)LeapPINVOKE.Gesture_Type_get(swigCPtr);

		public GestureState State => (GestureState)LeapPINVOKE.Gesture_State_get(swigCPtr);

		public int Id => LeapPINVOKE.Gesture_Id_get(swigCPtr);

		public long Duration => LeapPINVOKE.Gesture_Duration_get(swigCPtr);

		public float DurationSeconds => LeapPINVOKE.Gesture_DurationSeconds_get(swigCPtr);

		public Frame Frame
		{
			get
			{
				IntPtr intPtr = LeapPINVOKE.Gesture_Frame_get(swigCPtr);
				return (intPtr == IntPtr.Zero) ? null : new Frame(intPtr, true);
			}
		}

		public HandList Hands
		{
			get
			{
				IntPtr intPtr = LeapPINVOKE.Gesture_Hands_get(swigCPtr);
				return (intPtr == IntPtr.Zero) ? null : new HandList(intPtr, true);
			}
		}

		public PointableList Pointables
		{
			get
			{
				IntPtr intPtr = LeapPINVOKE.Gesture_Pointables_get(swigCPtr);
				return (intPtr == IntPtr.Zero) ? null : new PointableList(intPtr, true);
			}
		}

		public bool IsValid => LeapPINVOKE.Gesture_IsValid_get(swigCPtr);

		public static Gesture Invalid => new Gesture(LeapPINVOKE.Gesture_Invalid_get(), false);

		public Gesture(IntPtr cPtr, bool cMemoryOwn)
			: base(LeapPINVOKE.Gesture_SWIGUpcast(cPtr), cMemoryOwn)
		{
			swigCPtr = new HandleRef(this, cPtr);
		}

		public static HandleRef getCPtr(Gesture obj)
		{
			return obj?.swigCPtr ?? new HandleRef(null, IntPtr.Zero);
		}

		~Gesture()
		{
			Dispose();
		}

		public override void Dispose()
		{
			lock (this)
			{
				if (swigCPtr.Handle != IntPtr.Zero)
				{
					if (base.swigCMemOwn)
					{
						base.swigCMemOwn = false;
						LeapPINVOKE.delete_Gesture(swigCPtr);
					}
					swigCPtr = new HandleRef(null, IntPtr.Zero);
				}
				GC.SuppressFinalize(this);
				base.Dispose();
			}
		}

		public Gesture()
			: this(LeapPINVOKE.new_Gesture__SWIG_0(), true)
		{
		}

		public Gesture(Gesture rhs)
			: this(LeapPINVOKE.new_Gesture__SWIG_1(getCPtr(rhs)), true)
		{
			if (!LeapPINVOKE.SWIGPendingException.Pending)
			{
				return;
			}
			throw LeapPINVOKE.SWIGPendingException.Retrieve();
		}

		public bool Equals(Gesture rhs)
		{
			bool result = LeapPINVOKE.Gesture_Equals(swigCPtr, getCPtr(rhs));
			if (LeapPINVOKE.SWIGPendingException.Pending)
			{
				throw LeapPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public override string ToString()
		{
			return LeapPINVOKE.Gesture_ToString(swigCPtr);
		}
	}
}
